#ifndef CONF_VERSION_H_
#define CONF_VERSION_H_

#include "attribute.h"

namespace gpyp {
namespace conf {

#define DEF_VERSION_CMP_OPERATOR(T, C)          \
  bool operator C(const T &version) const;
#define DEF_VERSION_OPERATORS(T)                \
  const T &operator=(const T &version);         \
  DEF_VERSION_CMP_OPERATOR(T, ==)               \
  DEF_VERSION_CMP_OPERATOR(T, !=)               \
  DEF_VERSION_CMP_OPERATOR(T, <)                \
  DEF_VERSION_CMP_OPERATOR(T, <=)               \
  DEF_VERSION_CMP_OPERATOR(T, >)                \
  DEF_VERSION_CMP_OPERATOR(T, >=)

class Version {
private:
  Glib::ustring     str_;
  std::vector<uint> terms_;

public:
  static std::vector<uint> parse(const Glib::ustring &str);

  const Glib::ustring &get() const;
  const std::vector<uint> &get_terms() const;
  void set(const Version &version);
  void set(const Glib::ustring &version);

  DEF_VERSION_OPERATORS(Version)
  DEF_VERSION_OPERATORS(Glib::ustring)

  Version();
  Version(const Version &version);
  Version(const Glib::ustring &version);
};

std::ostream &operator<<(std::ostream &os, const Version &v);

extern Version version_current;

class AttributeVersion : public Attribute<Version, AttributeVersion> {
public:
  inline static Version to_value(const Glib::ustring &str) {
    return Version(str);
  }
  inline static Glib::ustring to_string(const Version &value) {
    return value.get();
  }

  inline AttributeVersion(const Glib::ustring &name, const Version &defval) :
    Attribute<Version, AttributeVersion>(name, defval)
  {
  }
};

class RefAttributeVersion : public RefAttribute<AttributeVersion> {
public:
  DEF_VERSION_OPERATORS(Version)
  DEF_VERSION_OPERATORS(Glib::ustring)

  RefAttributeVersion(const Glib::ustring &name,
                      const Version &def = version_current);
};

#undef DEF_VERSION_CMP_OPERATOR
#undef DEF_VERSION_OPERATORS

}/*conf*/
}/*gpyp*/

#endif/*CONF_VERSION_H_*/
